]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
Port to new GDBus bindings in gjs
authorGiovanni Campagna <gcampagna@src.gnome.org>
Tue, 16 Aug 2011 12:19:59 +0000 (14:19 +0200)
committerColin Walters <walters@verbum.org>
Fri, 11 Nov 2011 16:15:38 +0000 (11:15 -0500)
Rewrite code acquiring dbus names so that it uses GDBus, and rewrite
ShellDBus so that it is exposed on the GDBus connection. Ports of
the other objects will follow.

https://bugzilla.gnome.org/show_bug.cgi?id=648651

configure.ac
js/ui/main.js
js/ui/shellDBus.js
src/main.c

index a0fc3382736c60b2897e919fb111bb0a91f9448b..1304baae9225ea9f1a02c3648b2f71c863cab75e 100644 (file)
@@ -70,8 +70,7 @@ GJS_MIN_VERSION=1.29.18
 MUTTER_MIN_VERSION=3.2.1
 FOLKS_MIN_VERSION=0.5.2
 GTK_MIN_VERSION=3.0.0
-GLIB_MIN_VERSION=2.31.0
-GIO_MIN_VERSION=2.29.10
+GIO_MIN_VERSION=2.31.0
 LIBECAL_MIN_VERSION=2.32.0
 LIBEDATASERVER_MIN_VERSION=1.2.0
 LIBEDATASERVERUI_MIN_VERSION=2.91.6
@@ -81,9 +80,8 @@ POLKIT_MIN_VERSION=0.100
 STARTUP_NOTIFICATION_MIN_VERSION=0.11
 
 # Collect more than 20 libraries for a prize!
-PKG_CHECK_MODULES(GNOME_SHELL, glib-2.0 >= $GLIB_MIN_VERSION
-                               gio-2.0 >= $GIO_MIN_VERSION
-                               gio-unix-2.0 dbus-glib-1 libxml-2.0
+PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
+                              libxml-2.0
                                gtk+-3.0 >= $GTK_MIN_VERSION
                                folks >= $FOLKS_MIN_VERSION
                                libmutter >= $MUTTER_MIN_VERSION
index e08de3df84067ade13bf8d59bf37c3524eaf74c0..6bd5f59dcaaf2ce0ee5cf38835fd32911313e25f 100644 (file)
@@ -1,7 +1,6 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 
 const Clutter = imports.gi.Clutter;
-const DBus = imports.dbus;
 const Gdk = imports.gi.Gdk;
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
@@ -163,11 +162,6 @@ function start() {
     Gio.DesktopAppInfo.set_desktop_env('GNOME');
 
     shellDBusService = new ShellDBus.GnomeShell();
-    // Force a connection now; dbus.js will do this internally
-    // if we use its name acquisition stuff but we aren't right
-    // now; to do so we'd need to convert from its async calls
-    // back into sync ones.
-    DBus.session.flush();
 
     // Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
     // also initialize ShellAppSystem first.  ShellAppSystem
index 4f81c53a9ae9b630a399bc94bf71e0d996fff299..5a00a34f339dbc18e0f5ed16807ef2447231b368 100644 (file)
@@ -1,71 +1,70 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 
-const DBus = imports.dbus;
 const Lang = imports.lang;
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
 
 const Config = imports.misc.config;
 const ExtensionSystem = imports.ui.extensionSystem;
 const Main = imports.ui.main;
 
-const GnomeShellIface = {
-    name: 'org.gnome.Shell',
-    methods: [{ name: 'Eval',
-                inSignature: 's',
-                outSignature: 'bs'
-              },
-              { name: 'ListExtensions',
-                inSignature: '',
-                outSignature: 'a{sa{sv}}'
-              },
-              { name: 'GetExtensionInfo',
-                inSignature: 's',
-                outSignature: 'a{sv}'
-              },
-              { name: 'GetExtensionErrors',
-                inSignature: 's',
-                outSignature: 'as'
-              },
-              { name: 'ScreenshotArea',
-                inSignature: 'iiiis',
-                outSignature: 'b'
-              },
-              { name: 'ScreenshotWindow',
-                inSignature: 'bs',
-                outSignature: 'b'
-              },
-              { name: 'Screenshot',
-                inSignature: 's',
-                outSignature: 'b'
-              },
-              { name: 'EnableExtension',
-                inSignature: 's',
-                outSignature: ''
-              },
-              { name: 'DisableExtension',
-                inSignature: 's',
-                outSignature: ''
-              },
-              { name: 'InstallRemoteExtension',
-                inSignature: 'ss',
-                outSignature: ''
-              },
-              { name: 'UninstallExtension',
-                inSignature: 's',
-                outSignature: 'b'
-              }
-             ],
-    signals: [{ name: 'ExtensionStatusChanged',
-                inSignature: 'sis' }],
-    properties: [{ name: 'OverviewActive',
-                   signature: 'b',
-                   access: 'readwrite' },
-                 { name: 'ApiVersion',
-                   signature: 'i',
-                   access: 'read' },
-                 { name: 'ShellVersion',
-                   signature: 's',
-                   access: 'read' }]
-};
+const GnomeShellIface = <interface name="org.gnome.Shell">
+<method name="Eval">
+    <arg type="s" direction="in" name="script" />
+    <arg type="b" direction="out" name="success" />
+    <arg type="s" direction="out" name="result" />
+</method>
+<method name="ListExtensions">
+    <arg type="a{sa{sv}}" direction="out" name="extensions" />
+</method>
+<method name="GetExtensionInfo">
+    <arg type="s" direction="in" name="extension" />
+    <arg type="a{sv}" direction="out" name="info" />
+</method>
+<method name="GetExtensionErrors">
+    <arg type="s" direction="in" name="extension" />
+    <arg type="as" direction="out" name="errors" />
+</method>
+<method name="ScreenshotArea">
+    <arg type="i" direction="in" name="x"/>
+    <arg type="i" direction="in" name="y"/>
+    <arg type="i" direction="in" name="width"/>
+    <arg type="i" direction="in" name="height"/>
+    <arg type="s" direction="in" name="filename"/>
+    <arg type="b" direction="out" name="success"/>
+</method>
+<method name="ScreenshotWindow">
+    <arg type="b" direction="in" name="include_frame"/>
+    <arg type="s" direction="in" name="filename"/>
+    <arg type="b" direction="out" name="success"/>
+</method>
+<method name="Screenshot">
+    <arg type="s" direction="in" name="filename"/>
+    <arg type="b" direction="out" name="success"/>
+</method>
+<method name="EnableExtension">
+    <arg type="s" direction="in" name="uuid"/>
+</method>
+<method name="DisableExtension">
+    <arg type="s" direction="in" name="uuid"/>
+</method>
+<method name="InstallRemoteExtension">
+    <arg type="s" direction="in" name="uuid"/>
+    <arg type="s" direction="in" name="version"/>
+</method>
+<method name="UninstallExtension">
+    <arg type="s" direction="in" name="uuid"/>
+    <arg type="b" direction="out" name="success"/>
+</method>
+<property name="OverviewActive" type="b" access="readwrite" />
+<property name="ApiVersion" type="i" access="read" />
+<property name="ShellVersion" type="s" access="read" />
+<signal name="ExtensionStatusChanged">
+    <arg type="s" name="uuid"/>
+    <arg type="i" name="state"/>
+    <arg type="s" name="error"/>
+</signal>
+</interface>;
 
 function GnomeShell() {
     this._init();
@@ -73,7 +72,8 @@ function GnomeShell() {
 
 GnomeShell.prototype = {
     _init: function() {
-        DBus.session.exportObject('/org/gnome/Shell', this);
+        this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this);
+        this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
         ExtensionSystem.connect('extension-state-changed',
                                 Lang.bind(this, this._extensionStateChanged));
     },
@@ -156,11 +156,33 @@ GnomeShell.prototype = {
     },
 
     ListExtensions: function() {
-        return ExtensionSystem.extensionMeta;
+        let out;
+        for (let uuid in ExtensionSystem.extensionMeta) {
+            let dbusObj = this.GetExtensionInfo(uuid);
+            out[uuid] = dbusObj;
+        }
+        return out;
     },
 
     GetExtensionInfo: function(uuid) {
-        return ExtensionSystem.extensionMeta[uuid] || {};
+        let meta = ExtensionSystem.extensionMeta[uuid] || {};
+        let out;
+        for (let key in meta) {
+            let val = meta[key];
+            let type;
+            switch (typeof val) {
+            case 'object':
+                throw Error('Extension had a nested object in the metadata. This is not supported');
+            case 'string':
+                type = 's';
+                break;
+            case 'number':
+                type = 'd';
+                break;
+            }
+            out[key] = GLib.Variant.new(type, val);
+        }
+        return out;
     },
 
     GetExtensionErrors: function(uuid) {
@@ -211,6 +233,3 @@ GnomeShell.prototype = {
                                  [newState.uuid, newState.state, newState.error]);
     }
 };
-
-DBus.conformExport(GnomeShell.prototype, GnomeShellIface);
-
index d8cdff5b27a074c0a6ab95eaa20f7218e6432515..6cc66f83d54a5466c30a0dfc5fcc16b154ae672e 100644 (file)
@@ -11,7 +11,6 @@
 #include <cogl-pango/cogl-pango.h>
 #include <clutter/clutter.h>
 #include <clutter/x11/clutter-x11.h>
-#include <dbus/dbus-glib.h>
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
@@ -36,35 +35,41 @@ extern GType gnome_shell_plugin_get_type (void);
 
 static gboolean is_gdm_mode = FALSE;
 
+#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
+#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4
+
 static void
-shell_dbus_acquire_name (DBusGProxy *bus,
+shell_dbus_acquire_name (GDBusProxy *bus,
                          guint32     request_name_flags,
                          guint32    *request_name_result,
                          gchar      *name,
                          gboolean    fatal)
 {
   GError *error = NULL;
-  if (!dbus_g_proxy_call (bus, "RequestName", &error,
-                          G_TYPE_STRING, name,
-                          G_TYPE_UINT, request_name_flags,
-                          G_TYPE_INVALID,
-                          G_TYPE_UINT, request_name_result,
-                          G_TYPE_INVALID))
+  GVariant *request_name_variant;
+
+  if (!(request_name_variant = g_dbus_proxy_call_sync (bus,
+                                                       "RequestName",
+                                                       g_variant_new ("(su)", name, request_name_flags),
+                                                       0, /* call flags */
+                                                       -1, /* timeout */
+                                                       NULL, /* cancellable */
+                                                       &error)))
     {
-      g_printerr ("failed to acquire %s: %s\n", name, error->message);
-      if (fatal)
-        exit (1);
+      g_printerr ("failed to acquire org.gnome.Shell: %s\n", error->message);
+      exit (1);
     }
+  g_variant_get (request_name_variant, "(u)", request_name_result);
 }
 
 static void
-shell_dbus_acquire_names (DBusGProxy *bus,
+shell_dbus_acquire_names (GDBusProxy *bus,
                           guint32     request_name_flags,
                           gchar      *name,
                           gboolean    fatal, ...) G_GNUC_NULL_TERMINATED;
 
 static void
-shell_dbus_acquire_names (DBusGProxy *bus,
+shell_dbus_acquire_names (GDBusProxy *bus,
                           guint32     request_name_flags,
                           gchar      *name,
                           gboolean    fatal, ...)
@@ -89,27 +94,32 @@ shell_dbus_acquire_names (DBusGProxy *bus,
 static void
 shell_dbus_init (gboolean replace)
 {
-  DBusGConnection *session;
-  DBusGProxy *bus;
+  GDBusConnection *session;
+  GDBusProxy *bus;
+  GError *error = NULL;
   guint32 request_name_flags;
   guint32 request_name_result;
 
-  /* TODO:
-   * In the future we should use GDBus for this.  However, in
-   * order to do that, we need to port all of the JavaScript
-   * code.  Otherwise, the name will be claimed on the wrong
-   * connection.
-   */
-  session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+  session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
 
-  bus = dbus_g_proxy_new_for_name (session,
-                                   DBUS_SERVICE_DBUS,
-                                   DBUS_PATH_DBUS,
-                                   DBUS_INTERFACE_DBUS);
+  if (error) {
+    g_printerr ("Failed to connect to session bus: %s", error->message);
+    exit (1);
+  }
+
+  bus = g_dbus_proxy_new_sync (session,
+                               G_DBUS_PROXY_FLAGS_NONE,
+                               NULL, /* interface info */
+                               "org.freedesktop.DBus",
+                               "/org/freedesktop/DBus",
+                               "org.freedesktop.DBus",
+                               NULL, /* cancellable */
+                               &error);
 
-  request_name_flags = DBUS_NAME_FLAG_DO_NOT_QUEUE | DBUS_NAME_FLAG_ALLOW_REPLACEMENT;
+  request_name_flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
   if (replace)
     request_name_flags |= DBUS_NAME_FLAG_REPLACE_EXISTING;
+
   shell_dbus_acquire_name (bus,
                            request_name_flags,
                            &request_name_result,
@@ -117,8 +127,7 @@ shell_dbus_init (gboolean replace)
   if (!(request_name_result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
         || request_name_result == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER))
     {
-      g_printerr ("%s already exists on bus and --replace not specified\n",
-                  SHELL_DBUS_SERVICE);
+      g_printerr (SHELL_DBUS_SERVICE " already exists on bus and --replace not specified\n");
       exit (1);
     }
 
@@ -126,7 +135,8 @@ shell_dbus_init (gboolean replace)
    * We always specify REPLACE_EXISTING to ensure we kill off
    * the existing service if it was running.
    */
-  request_name_flags |= DBUS_NAME_FLAG_REPLACE_EXISTING;
+  request_name_flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;
+
   shell_dbus_acquire_names (bus,
                             request_name_flags,
   /* Also grab org.gnome.Panel to replace any existing panel process */
@@ -142,6 +152,7 @@ shell_dbus_init (gboolean replace)
                            &request_name_result,
                            "org.gnome.Caribou.Keyboard", FALSE);
   g_object_unref (bus);
+  g_object_unref (session);
 }
 
 static void